library RectUtils initializer Init requires Table
//===========================================================================
// RECT UTILS v 1.2 By Wareditor - 21 / 07 / 12
//===========================================================================
//
// AIM :
//
// * Add GetTriggeringRect()
// * Attach id to saved rect
// ：* Easy "gate" system
//
// API :
//
// FUNCTIONS :
// * call SaveRect( rect, id )
// - Save a rect and attach a id to it.
// The GetTriggeringRect will only work with saved rect
//
// * call ReleaseRect( rect )
// - Release a saved rect
//
// * call RegionAddRectSaved( region, rect )
// - Add a saved rect to a region
// If you use the native, it will break the system in certain condition
//
// * call SetRectId( rect, id )
// - Change the id of a saved rect
//
// * call GetRectId( rect )
// - Return the id of the rect
//
// * call GetTriggeringRect()
// - Return the triggering rect of a Unit Enters Event and Leaves Event
//
// COMMENTARY :
//
// * Please give credits
//
// REQUIRES :
//
// * vJass + New Jass Helper
//
//
//===========================================================================
// GLOBALS - NO TOUCH
//===========================================================================

    globals

        private Table tb
        private region TriggerRegion = null
        private trigger Trig = CreateTrigger()

    endglobals

    //===========================================================================
    // GET TRIGGERING RECT
    //===========================================================================

    function GetTriggeringRect takes nothing returns rect
        return tb.rect[GetHandleId(TriggerRegion)]
    endfunction

    private function EnterLeave takes nothing returns nothing
        set TriggerRegion = GetTriggeringRegion()
    endfunction


    //===========================================================================
    // ID
    //===========================================================================

    function SetRectId takes rect r, integer id returns nothing
        set tb.integer[GetHandleId(r)] = id
    endfunction

    function GetRectId takes rect r returns integer
        return tb.integer[GetHandleId(r)]
    endfunction

    //===========================================================================
    // SAVE
    //===========================================================================

    function Saved takes rect r returns boolean
        return tb.region.has(GetHandleId(r))
    endfunction

    function SaveRect takes rect r, integer id returns nothing
        local region reg

        if not Saved(r) then

            set reg = CreateRegion()
            call RegionAddRect(reg, r)

            set tb.integer[GetHandleId(r)] = id
            set tb.rect[GetHandleId(reg)] = r
            set tb.region[GetHandleId(r)] = reg

            call TriggerRegisterEnterRegion(Trig, reg, null)
            call TriggerRegisterLeaveRegion(Trig, reg, null)

            set reg = null
        endif
    endfunction

    function ReleaseRect takes rect r returns nothing
        local integer i
        local region reg

        if Saved(r) then

            set reg = tb.region[GetHandleId(r)]
            call RegionClearRect(reg, r)

            call tb.integer.remove(GetHandleId(r))
            call tb.handle.forget(reg)
            call tb.handle.forget(r)

            set reg = null
        endif
    endfunction

    function RegionAddRectSaved takes region whichRegion, rect r returns nothing
        local region reg = tb.region[GetHandleId(r)]

        if reg != null then
            call RegionAddRect(whichRegion, r)
            call RegionClearRect(reg, r)//May seem useless but no
            call RegionAddRect(reg, r)
        endif

        set reg = null
    endfunction

    function RegisterRectEvent takes rect r, code onEnter, code onLeave returns nothing
        local trigger t = null
        local region rg = null
        local boolean b = (onEnter != null)
        local boolean c = (onLeave != null)
        local boolean d = (b or c)

        if (d) then
            set rg = CreateRegion()
            call RegionAddRect(rg, r)
        endif

        if (b) then
            set t = CreateTrigger()
            call TriggerRegisterEnterRegion(t, rg, null)
            call TriggerAddCondition(t, Filter(onEnter))
            set t = null
        endif

        if (c) then
            set t = CreateTrigger()
            call TriggerRegisterLeaveRegion(t, rg, null)
            call TriggerAddCondition(t, Filter(onLeave))
            set t = null
        endif

        if (d) then
           set rg = null
        endif
    endfunction

    //===========================================================================
    // INITALIZATION
    //===========================================================================

    private function Init takes nothing returns nothing
        set tb = Table.create()
        call TriggerAddAction(Trig, function EnterLeave)
    endfunction

endlibrary
